using Basis;
using DG.Tweening;
using NL.SpriteAnimation;
using System.Collections.Generic;
using UnityEngine;


namespace NL.Advanced
{
    public interface IBBOwner
    {
        GameObject Mod_BB { get; set; }
    }
    public class BulletJump
    {
        public enum JumpMode
        {
            Line,//线性，不允许回弹
            SpringBack,//允许回弹
        }

        public JumpMode Mode = JumpMode.Line;

        public float MaxDistance = float.MaxValue;

        private HashSet<ICombatOwner> _History = new HashSet<ICombatOwner>();
        private ICombatOwner _LastTarget = null;

        public bool CanHit(ICombatOwner _owner)
        {
            if (Mode == JumpMode.Line)
            {
                return !_History.Contains(_owner);
            }
            else if (Mode == JumpMode.SpringBack)
            {
                return _LastTarget != _owner;
            }
            return false;
        }

        public void Hit(ICombatOwner _owner)
        {
            if (_owner == null) return;
            _History.Add(_owner);
            _LastTarget = _owner;
        }
    }

    public enum BulletMotionType
    {
        normal,
        jump,//类闪电链
    }

    public enum BulletTargetMode
    {
        TargetOnly = 0, ByCollider = 1,
    }
    public enum BulletDeadMode
    {
        None = 0,
        HitCount = 1,
        MapOnly = 4,
        Any = 5,
        ByLife = 11,
        ByDistance = 12,
        WithSkill = 21,
        WithOwner = 22,
    }

    public enum BBSecondStageMode
    {
        EachHit = 1,
        Dead = 2,
        FirstHit =3,
    }

    // [RequireComponent(typeof(Collider))]
    public partial class BB : LivingOBJ, ITargetable, IOwnerable<ICombatOwner>, IAttackerOwner
    {
        private string _MotionData;
        private BulletMotionType _MotionType = BulletMotionType.normal;
        private BulletJump _JumpInfo;



        Target ITargetable.Target => NowTarget;
        void ITargetable.SetTarget(GameObject who) => SetTarget(who);
        void ITargetable.SetTarget(Vector3 pos) => SetTarget(pos);

        public ICombatOwner Owner => _CombatOwner;

        ICombatOwner IAttackerOwner.CombatOwner => _CombatOwner;

        void IAttackerOwner.SetCombat(NL.Advanced.ICombatOwner _owner, NL.Advanced.BB _bb)
        { }

        BB IAttackerOwner.BBOwner => this;


        private NLIni _Info;




        [Header("目标模式 仅目标有效 ; 碰撞体检测")]
        public BulletTargetMode TargetMode = BulletTargetMode.TargetOnly;


        [Header("有效性,阵营有效..不再有作用 使用Attacker的阵营判断.")]
        public CampType AvliableCamp = CampType.Enemy;

        [Header("消失的条件模式: 不管理; 有效击中的次数, 击中任何 , 按照时间,按照运行距离 ")]
        public BulletDeadMode DeadMode = BulletDeadMode.HitCount;
        public float DeadData = 1;

        [Header("子弹击中对象/消亡的时候出发的特效(默认生命周期1秒).")]
        public GameObject Mod_Hit;
        public Color HitColor = Color.red;
        public float HitColorLife = 0.3f;

        [Header("子弹击中消亡的时候触发得对象; 是否延长子弹得生命.")]
        public GameObject Mod_Dead;
        public float UseDeadFactor = 1;


        [Header("方向模式 不控制 ;始终面向目标; 运动方向")]
        public BulletFaceMode FaceMode = BulletFaceMode.none;



        [Header("战斗部结算因子-用于对战斗结算得缩放得倍数.默认是1.")]
        public float Factor = 1;
        //[Header("战斗部增伤因子-用于对战斗结算得增伤.默认是0.")]
        //public float EnhanceDamage = 0f;

        public bool Skill;

        //[Header("---RUNTIME---- 时长,运动距离,击中次数 ")]


        protected float _Lifing;
        protected float _Disting;
        protected int _HitCount;


        private BB DeadBB;

        // protected ILevelStateOwner _LevelOwner;
        protected GameObject _LauncherOwner;
        public GameObject LauncherOwner => _LauncherOwner;

        protected PropertyCC _LauncherProperty;

        public PropertyCC LauncherProperty => _LauncherProperty;

        protected IBBRuningData _BBRuntime;

        protected ICombatOwner _CombatOwner;
        public ICombatOwner CombatOwner => _CombatOwner;

        public Target NowTarget = new Target();
        [SerializeField]
        private ICombatOwner[] ExcludeCombatOwners;

        public GameObject Mod_SecondLauncher;

        public BBSecondStageMode SecondStageMode = BBSecondStageMode.EachHit;
        public BB SetTarget(GameObject who)
        {
            _BornToTarget = who;
            NowTarget.Set(who); return this;
        }
        GameObject _BornToTarget;

        protected bool ShowUI = false;

        public void SetShowUI(bool _showUI)
        {
            ShowUI = _showUI;
        }

        public BB SetTarget(Vector3 pos)
        {
            NowTarget.Set(pos); return this;
        }

        public BB SetExcludeCombatOwners(ICombatOwner[] list)
        {
            ExcludeCombatOwners = list;
            return this;
        }

        //public void SetLevelStateOwner(ILevelStateOwner _owner)
        //{
        //    _LevelOwner = _owner;
        //}
        public BB SetCombatOwner(ICombatOwner _owner, float comboCoefficient)
        {
            _CombatOwner = _owner;
            return this;
        }
        public BB SetLauncherOwner(GameObject owner)
        {
            _LauncherOwner = owner;
            //gameObject.INFOSet(owner.gameObject);
            _Info = gameObject.INFO();

            return this;
        }

        //public BB SetEnhanceDamage(float damage)
        //{
        //    EnhanceDamage = damage;
        //    return this;
        //}

        //public BB SetFactor(float factor)
        //{
        //    Factor = factor; return this;
        //}



        public void SetMotionInfo(BulletMotionType _type, string _data)
        {
            _MotionType = _type;
            _MotionData = _data;
        }

        [Header("是否允许发射器根据属性修正BB自身的Size(缩放)")]
        public bool AllowSkillPropertyReSize = false;
        float _Size = 1;


        string _OldName;
        protected Rigidbody _Rigi;

        Collider[] _Colliders;
        Vector3 _LastPos;
        //private TeamManager _TeamManager;
        Vector3 _ScaleInit;
        protected virtual void Awake()
        {

            if (TimeForBorn <= 0) TimeForBorn = 0.02f;

            _OldName = name;
            _Colliders = GetComponentsInChildren<Collider>();

            _LastPos = transform.position;
            _ScaleInit = transform.localScale;
            var bbList = GetComponentsInChildren<BB>(true);
            foreach (var bb in bbList)
            {
                if (bb.gameObject != this.gameObject)
                {
                    DeadBB = bb;
                }
            }

            _Moving = GetComponent<SpriteMoving>();
            _Targeting = GetComponent<SpriteTargeting>();
            _Linking = GetComponent<SpriteLinking>();

            _CombatOwner = GetComponentInParent<ICombatOwner>();
            if (ExcludeCombatOwners != null)
            {

            }
            Close();

        }



        void ProcMotionInfo()
        {
            if (_MotionType == BulletMotionType.jump)
            {
                _JumpInfo = new BulletJump();
                var arr = _MotionData.Split(NLConst.CHAR_INNER);
                var times = int.Parse(arr[0]);
                var springBack = arr[1] == "1";
                if (arr.Length > 2)
                {
                    _JumpInfo.MaxDistance = float.Parse(arr[2]);
                }
                DeadMode = BulletDeadMode.HitCount;
                DeadData = times;
                _JumpInfo.Mode = springBack ? BulletJump.JumpMode.SpringBack : BulletJump.JumpMode.Line;
                TargetMode = BulletTargetMode.TargetOnly;
            }
        }
        static uint NNNDDD = 30234;

        [Header("导弹初始缩放=0; 延迟xx后恢复正常.")]
        public float SelfZoomOneDelay = 0.1f;

        //击中得 目标
        [Header("击中得目标列表.")]
        public List<GameObject> __Hited=new List<GameObject>();


        public static void CLEAR_HashBoard()
        {
            CountLiving = 0; CountLived = 0; CountDead = 0;
        }
        public static int CountLiving;
        public static int CountLived;
        public static int CountDead;
        protected override void OnLive()
        {
            base.OnLive();


            CountLived++;

            CountLiving++;

            __Hited.Clear();

            _BBRuntime = GetComponent<IBBRuningData>();

            _LauncherProperty = _LauncherOwner != null ? _LauncherOwner.GetComponent<PropertyCC>() : null;

            transform.localScale = Vector3.zero;

            transform.DOScale(_ScaleInit * _Size, 0f).SetDelay(SelfZoomOneDelay*0.2f);


            _Rigi = gameObject.RIGINormalize();

            gameObject.layer = LayerMask.NameToLayer("BB");
            name = $"{_OldName}_{NNNDDD++}";

            if (CombatSetting.LOGable)
                LOG.Add($"[BB.OnLive()]..{name}");

            _LastPos = transform.position;
            _Lifing = 0;
            _Disting = 0;
            _HitCount = 0;


            ProcMotionInfo();

            if (DeadMode == BulletDeadMode.WithOwner)
            {
                if (_CombatOwner != null && _CombatOwner.gameObject != null) _CombatOwner.gameObject.WAITDisable((w) =>
                 {
                     _DoDead();
                 });
            }
            else if (DeadMode == BulletDeadMode.WithSkill)
            {
                if (_LauncherOwner != null && _LauncherOwner.gameObject != null) _LauncherOwner.gameObject.WAITDisable((w) =>
                {
                    _DoDead();
                });
            }

            _ResetSpeed();

            _ResetLife();

            Open();


        }
        protected override void OnDead()
        {
            base.OnDead();

            CountDead++;
            CountLiving--;
        }
        protected override void OnDisable()
        {
            base.OnDisable();


            transform.localScale = Vector3.zero;

            var rigi = GetComponent<Rigidbody>();
            if (rigi != null)
            {
                Destroy(rigi);
            }
        }

        protected virtual void Reset()
        {

        }

        protected virtual void _DoHit(ICombatOwner who)
        {
            if (who == null || !who.Living || who.gameObject == null)
            {
                if (!Skill)
                {
                    _DoDead();
                    return;
                }
            }

            if (CombatSetting.LOGable)
                LOG.Add($"[HITTEST:BB._DoHit]{who?.gameObject}");


            __Hited.Add(who.gameObject);


            IAttacker[] _atts = GetComponents<IAttacker>();
            bool _hited = false;
            foreach (var att in _atts)
            {
                att.ShowUI = ShowUI;
                var result = att.Attack(who);
                if (result.Avilable)
                    _hited = true;
            }

            if (!_hited) return;

            if (Mod_Hit != null)
                EFF.CreateEFF(Mod_Hit, who?.gameObject);
            //if (HitColorLife > 0)
            //{
            //    who?.HitColor(HitColor, HitColorLife);
            //}

            //二段伤害的触发,每次伤害时处理
            if (Mod_SecondLauncher != null && SecondStageMode == BBSecondStageMode.EachHit)
            {
                this.ADDNewLaunch(Mod_SecondLauncher,
                    transform.position,
                    __Hited);
            }

            // 按击中次数的 Dead 判断.
            if (DeadMode == BulletDeadMode.HitCount)
            {
                if (_hited)
                {
                    _HitCount += 1;

                    if(_HitCount == 1 && Mod_SecondLauncher != null && SecondStageMode == BBSecondStageMode.FirstHit)
                    {
                        this.ADDNewLaunch(Mod_SecondLauncher,
                            transform.position,
                            __Hited);
                    }

                    if (_HitCount >= DeadData + (_BBRuntime == null ? 0 : _BBRuntime.Cross))
                    {
                        _DoDead();
                    }
                    else
                    {
                        //还有次数
                        if (_MotionType == BulletMotionType.jump)
                        {
                            _JumpInfo.Hit(who);
                            //弹跳类子弹
                            //根据类型查找下一个目标
                            var minDis = float.MaxValue;
                            ICombatOwner _target = null;

                            //var unitRecord = _TeamManager?.Units;
                            //if (unitRecord != null)
                            //{
                            //    foreach (var pair in unitRecord.Units)
                            //    {
                            //        foreach (var unit in pair.Value)
                            //        {
                            //            if (unit.Equals(null))
                            //                continue;
                            //            //检查是否能攻击
                            //            foreach (var att in _atts)
                            //            {
                            //                var result = att.CanAttack(unit);
                            //                if (result)
                            //                {
                            //                    //检测是否已攻击过
                            //                    if (!_JumpInfo.CanHit(unit))
                            //                        continue;
                            //                    //判断距离
                            //                    var dis = Vector3.Distance(transform.position, unit.transform.position);
                            //                    if (dis <= _JumpInfo.MaxDistance && dis < minDis)
                            //                    {
                            //                        minDis = dis;
                            //                        _target = unit;
                            //                    }
                            //                }
                            //            }
                            //        }
                            //    }
                            //}

                            if (_target != null)
                            {
                                Reset();
                                _JumpInfo.Hit(_target);
                                if (CombatSetting.LOGable) 
                                    LOG.Add($"{gameObject}跳跃攻击下一个目标，{_target.gameObject}");
                                Close();
                                //执行攻击逻辑
                                NowTarget.Set(_target.gameObject);
                                Open();
                            }
                            else
                            {
                                _DoDead();
                            }
                        }
                    }
                }
            }
        }


        protected virtual void _DoDead()
        {


            if (Mod_Dead != null)
            {

                var eff = EFF.CreateEFF(Mod_Dead, gameObject);

                BB _bb = eff.GetComponentInChildren<BB>();

                if (_bb != null)
                {
                    //_bb.SetFactor(UseDeadFactor);

                    var atts = GetComponents<Attacker>();
                    foreach (var att in atts)
                    {
                        _bb.gameObject.AddComponent<Attacker>()
                            .Set(att.InitStr).SetShowUI(ShowUI).SetDisposable(true);
                    }
                }

                _bb?.SetCombatOwner(_CombatOwner, 1).SetLauncherOwner(_LauncherOwner);
            }

            //二段伤害技能
            if (Mod_SecondLauncher != null && SecondStageMode == BBSecondStageMode.Dead)
            {
                this.ADDNewLaunch(Mod_SecondLauncher,
                    transform.position,
                    __Hited);

            }

            gameObject.SetActive(false);

            //if (_DeadActions != null)
            //{
            //    foreach (var d in _DeadActions)
            //        d.WaitEnd(()=>
            //        {
            //            _Dead();
            //        }).Do();
            //}else
            //{
            //    _Dead();
            //}





        }

        //死亡后的处理，添加散射等特效
        protected override void _Dead()
        {
            base._Dead();
            //临时 关闭掉...后面有BUG,,


        }
        protected virtual void OnTriggerEnter(Collider other)
        {
            if (!Living) return;

            //LOG.Add($"[BB.OnTriggerEnter @{name}]: {other}");

            // 击中地面
            if (/* (DeadMode == BulletDeadMode.Any || DeadMode == BulletDeadMode.MapOnly) &&*/
                 other.gameObject.layer == LayerMask.NameToLayer("Map"))
            {
                _DoDead();
                if (CombatSetting.LOGable)
                    LOG.Add("[Attacker.OnTriggerEnter]:_DoDead In Map ");
                return;
            }



            //如果没有Body ;或者Body战斗无效..就忽略本次碰撞
            Body whobody = other.GetComponentInParent<Body>();
            if (whobody == null || !whobody.Combatable) return;

            //是否是自己? 就忽略本次碰撞
            if (AvliableCamp != CampType.Self && whobody.IsOwnerSelf(_CombatOwner)) return;


            //阵营 判断. [已经取消, 使用attack的阵营判断]
            if (!Camp.ISCampOf(AvliableCamp, _CombatOwner, whobody.CombatOwner))
            {
                if (CombatSetting.LOGable) 
                    LOG.Add("[Attacker.Attack]AvliableCamp NONONONON ");
                return;
            }

            //判断忽略..
            if (gameObject.IGNORHas(whobody.CombatOwner.gameObject))
            {
                return ;
            }

            //Logger.Log($"{gameObject}接收TriggerEnter，{_whobody.CombatOwner.gameObject.name}");



            //BB 的目标方式 判断
            switch (TargetMode)
            {
                case BulletTargetMode.TargetOnly:
                    if (whobody.CombatOwner != null && !NowTarget.Is(whobody.CombatOwner.gameObject))
                        return;
                    break;
                case BulletTargetMode.ByCollider:

                default: break;
            }



            _DoHit(whobody.CombatOwner);
            //_HitedPool.Add(whobody.CombatOwner);



            // 逻辑伤害 开始
            //_DoHit(_whobody.CombatOwner);

        }



        List<ICombatOwner> _HitedPool = new List<ICombatOwner>();
        protected Vector3 _MovingSpeed;
        protected virtual void Update()
        {


            if (!Living)
                return;

            //if (_HitedPool.Count > 0)
            //{
            //    _DoHit(_HitedPool[0]);
            //    _HitedPool.RemoveAt(0);
            //}


            _Lifing += Time.deltaTime;

            _MovingSpeed = (transform.position - _LastPos) / Time.deltaTime;


            _Disting += Vector3.Distance(transform.position, _LastPos);

            _LastPos = transform.position;

            switch (DeadMode)
            {
                case BulletDeadMode.ByLife:
                    if (_Lifing > DeadData)
                        _DoDead();
                    break;
                case BulletDeadMode.ByDistance:
                    if (_Disting > DeadData)
                        _DoDead();
                    break;
            }

            _HandleDirection();
        }
        protected void _HandleDirection()
        {
            //处理 运行中得 方向处理.
            switch (FaceMode)
            {
                case BulletFaceMode.ForceTarget:
                    Vector3 _targetpos = NowTarget.SetMount("Center").Position;
                    transform.forward = (_targetpos - transform.position).normalized;
                    break;
                case BulletFaceMode.BySpeed:
                    if (_MovingSpeed.magnitude >= 1)
                        transform.forward = _MovingSpeed.normalized;// _Speeding.normalized;
                    break;
                default:
                    break;
            }
        }

        public BB SetSize(float _size)
        {
            _Size = _size; return this;
        }

        public BB Open()
        {
            if (_Colliders != null)
            {
                foreach (var cc in _Colliders)
                {
                    cc.enabled = true;
                }
            }

            return this;
        }
        public BB Close()
        {
            if (_Colliders != null)
            {
                foreach (var cc in _Colliders)
                {
                    cc.enabled = false;
                }
            }

            return this;
        }



        //protected GameObject _CreateDeadBB(EmissionData emm,ILauncherOwner target = null)
        //{
        //    Transform _lauchroot;
        //    if (emm.Owner != null)
        //        _lauchroot = emm.Owner;
        //    else
        //        _lauchroot = transform;

        //    GameObject gBB = BPoolMan.POOL["BB"].Create(DeadBB.gameObject);//Instantiate(DeadBB.gameObject);
        //    gBB.transform.localPosition = transform.TransformPoint(emm.Position);
        //    gBB.transform.forward = transform.TransformDirection(emm.Direction);
        //    ICombatOwner[] list = new ICombatOwner[1];
        //    if (_BornToTarget)
        //    {
        //        var excludeCombatOwner = _BornToTarget.GetComponentInChildren<ICombatOwner>();
        //        if (excludeCombatOwner != null)
        //        {
        //            list[0] = excludeCombatOwner;
        //        }
        //    }
        //    gBB.GetComponent<BB>()?.SetCombatOwner(_CombatOwner, 1).SetExcludeCombatOwners(list);
        //    if(target != null)
        //    {
        //        gBB.GetComponent<BB>()?.SetTarget(target.gameObject);
        //    }

        //     //   gBB.GetComponent<BB>().AttackSecondaryRatio = _CombatOwner.GenarateAttackSecondaryRatio();

        //    return gBB;
        //}


    }

    public static class BBExntends
    {
        public static GameObject ADDNewLaunch(this Attacker who, GameObject Mod, Vector3 Position, List<GameObject> __Hited)
        {
            if (who == null) return null;
            var bb = who.Owner;
            if (bb == null) return null;

            if(__Hited == null || __Hited.Count == 0)
            {
                __Hited = bb.__Hited;
            }
            return ADDNewLaunch(bb, Mod, Position, __Hited);
        }
        /// <summary>
        /// 添加次生技能
        /// </summary>
        /// <param name="who">BB</param>
        /// <param name="Mod">Skill的Perfab</param>
        /// <param name="Position">位置</param>
        /// <param name="__Hited">排除列表</param>
        public static GameObject ADDNewLaunch(this BB who,GameObject Mod,Vector3 Position,  List<GameObject> __Hited)
        {
            GameObject newlauncher = GameObject.Instantiate(Mod);//BPoolMan.POOL["SKILL"].Create(Mod_SecondLauncher);


            //忽略目标
            newlauncher.IGNORAdd(__Hited);
            //


            newlauncher.transform.position = Position;
            Passivity passivity = newlauncher.GetComponent<Passivity>();
            if (passivity != null)
            {
                passivity.CombatOwner = who.CombatOwner;
                passivity.ParentLauncherOwner = who.LauncherOwner;
            }
            newlauncher.gameObject.INFOSet(Mod.INFO());

            return newlauncher;
        }
    }
}

